package com.admin.controller.admin;

import com.alibaba.fastjson2.JSON;
import com.common.util.MessageUtils;
import com.common.util.ProbjectUtils;
import com.system.util.RedisUtils;
import com.common.util.manager.AsyncManager;
import com.common.util.manager.factory.AsyncFactory;
import com.google.code.kaptcha.Producer;
import com.system.constant.Constants;
import com.system.constant.HTTPStatus;
import com.system.response.Result;
import com.common.token.JwtToken;
import com.common.util.JwtUtil;
import com.system.entity.Teacher;
import com.system.response.login.LoginDto;
import com.system.service.TeacherService;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

@Controller
@Slf4j
public class LoginController {

    @Autowired
    private TeacherService teacherService;

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private Producer producer;

    @ApiOperation("获取验证码")
    @GetMapping("/code")
    public ModelAndView code(String time, HttpServletResponse response) throws IOException {
        StringBuffer key = new StringBuffer();
        key.append(time).append("-").append(Constants.KAPTCHA_SESSION_KEY);

        //响应的过期时间，通过将Expires字段设置为0，可以告诉浏览器不要缓存这个响应，每次都需要重新请求服务器获取最新的数据。
        response.setDateHeader("Expires", 0);

        // 设置标准 HTTP1.1 无缓存标头。
        response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");

        // 设置 IE 扩展 HTTP1.1 无缓存标头（使用 addHeader）。
        response.addHeader("Cache-Control", "post-check=0, pre-check=0");

        // 设置标准 HTTP1.0 无缓存标头。
        response.setHeader("Pragma", "no-cache");

        // 返回一个 jpeg
        response.setContentType("image/jpeg");

        // 为图像创建文本
        String capText = producer.createText();

        // 为图像创建文本
        if (!StringUtils.isEmpty(time)){
            //时间戳不为空才加入缓存
            redisUtils.set(key.toString(),capText,5L);
        }
        // 用文本创建图像
        BufferedImage bi = producer.createImage(capText);

        ServletOutputStream out = response.getOutputStream();

        // 将数据写出
        ImageIO.write(bi, "jpg", out);
        try {
            out.flush();
        } finally {
            out.close();
        }
        return null;
    }

    @ApiOperation("登录接口")
    @ResponseBody
    @PostMapping("/login")
    public Result login(@Validated @RequestBody LoginDto loginDto, HttpServletRequest request) {
        if (StringUtils.isEmpty(loginDto.getUsername()) || StringUtils.isEmpty(loginDto.getPassword())) {
            return new Result().setCode(HTTPStatus.BAD_REQUEST).setMessage("账号或密码不能为空");
        }
//        if (StringUtils.isEmpty(loginDto.getCode())){
//            return new Result().setCode(HTTPStatus.BAD_REQUEST).setMessage("验证码不能为空");
//        }
        Object redisCode = redisUtils.get(loginDto.getTime()+"-"+ Constants.KAPTCHA_SESSION_KEY);

        if (!redisCode.toString().equals(loginDto.getCode())){
            redisUtils.delete(loginDto.getTime()+"-"+ Constants.KAPTCHA_SESSION_KEY);//移除当前验证码
            return new Result().setCode(HTTPStatus.BAD_REQUEST).setMessage("验证码不正确");
        }

        Subject subject = SecurityUtils.getSubject();
        String token = JwtUtil.createJWT(loginDto.getUsername(), "back", "teacher", 1000 * 60 * 60 * 24);
        JwtToken jwtToken = new JwtToken(token, loginDto.getPassword());
        subject.login(jwtToken);
        Teacher backTeacher = teacherService.getTeacherByUserName(loginDto.getUsername());
        backTeacher.setPassword("******");
        Map<String, Object> map = new HashMap<>();
        map.put("teacher", backTeacher);
        map.put("token", token);

        //将用户信息存入redis缓存中 格式：username
        redisUtils.set(backTeacher.getUsername(), JSON.toJSONString(backTeacher));

        redisUtils.delete(loginDto.getTime()+"-"+Constants.KAPTCHA_SESSION_KEY);//移除当前验证码

        //新增登录成功的日志
        AsyncManager.me().execute(AsyncFactory.recordLogininfor(loginDto.getUsername(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
        return new Result().setCode(HTTPStatus.SUCCESS).setMessage("登录成功").setData(map);
    }

    @Autowired
    private ProbjectUtils probjectUtils;

    @GetMapping("/logout")
    @ResponseBody
    public Result logout() {
        Subject subject = SecurityUtils.getSubject();
        //清除用户缓存
        probjectUtils.clearAllCache((String) subject.getPrincipal());

        SecurityUtils.getSubject().logout();
        return new Result().setCode(HTTPStatus.SUCCESS).setMessage("成功退出");
    }
}
